import java.util.Arrays;
import java.util.Scanner;

/**
 * 
 * @author victor
 * 
 */
public class Skyline {

	/**
	 * Funcion principal
	 * @param args
	 */
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int num_edificios, edificios_por_pedir; // numero de edificios
		int contador; // contador de datos de entrada
		int[][] entrada, // matriz con los datos de entrada
		salida; // matriz con los datos de salida

		contador = 0; // contador de edificios guardados 

		try {
			// almacena el numero de edificios totales
			num_edificios = Integer.parseInt( sc.nextLine() );
			edificios_por_pedir = num_edificios;
			entrada = new int[num_edificios][3]; // tamano de matriz

			// pide al usuario datos de edificios
			while (edificios_por_pedir > 0) {
				String temp = sc.nextLine();
				String[] partes = temp.split(" ");
				entrada[contador][0] = Integer.parseInt(partes[0]); // inicio de edificio
				entrada[contador][1] = Integer.parseInt(partes[1]); // fin de edificio
				entrada[contador][2] = Integer.parseInt(partes[2]); // altura de edificio
				contador++;
				edificios_por_pedir--;
			}

			// inicializa la generacion del nskyline
			salida = inicializacion_DyV( entrada );
			
			// imprime el resultado skyline
			imprime_Skyline( salida );

		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
	
	/**
	 * Imprime por patalla el skyline
	 * @param skyline matriz skyline con datos a imprimir
	 */
	public static void imprime_Skyline(int[][] skyline) {
		for(int i=0; i<skyline.length; i++) {
			// imprime "coordenada altura"
			System.out.println(skyline[i][0] + " " + skyline[i][1]);
		}
	}

	/**
	 * Inicializa la creacion de un skyline de todos los edificios
	 * @param edificios
	 * @return
	 */
	public static int[][] inicializacion_DyV(int[][] edificios) {
		return nucleo_DyV(edificios, 0 , edificios.length-1);
	}
	
	/**
	 * creacion de un skyline a partir de pequeños skyline
	 * @param edificios edificios iniciales
	 * @param edif_inicio primer edificio de skyline
	 * @param edif_fin ultimo edificio de skyline
	 * @return
	 */
	public static int[][] nucleo_DyV(int[][] edificios,int edif_inicio, int edif_fin) {
		// caso base del minimo skyline - un solo edificio
		if (edif_inicio == edif_fin){
			int[][] skyline = new int[2][2];
			// comienzo
			skyline[0][0] = edificios[edif_inicio][0]; // coordenada
			skyline[0][1] = edificios[edif_inicio][2]; // altura
			// fin
			skyline[1][0] = edificios[edif_inicio][1]; // coordenada
			skyline[1][1] = 0; // guarda 0 indicando fin de edificio
			return skyline;
		}
		// mitad de skyline
		int edif_medio = (edif_inicio + edif_fin) / 2;
		// primera mitad
		int[][] skyline_uno = nucleo_DyV(edificios, edif_inicio, edif_medio);
		// segunda mitad
		int[][] skyline_dos = nucleo_DyV(edificios, edif_medio+1, edif_fin);
		// mezcla de edificios
		return mezcla_Skyline(skyline_uno, skyline_dos);
	}
	
	/**
	 * junta dos skyline en uno
	 * @param skyline_uno primer skyline
	 * @param skyline_dos segundo skyline
	 * @return skyline resultante de la mezcla
	 */
	public static int[][] mezcla_Skyline(int[][] skyline_uno, int[][] skyline_dos) {
		
		int altura_anterior_uno = -1, // inializar altura anterior uno a negativo
		altura_anterior_dos = -1, // inializar altura anterior dos a negativo
		altura_anterior_aux = -1; // inializar altura anterior auxiliar a negativo
		
		// maximo tamaño posible de skyline
		int[][] skyline_mezclado = new int[ skyline_uno.length + skyline_dos.length ][2];
		
		int contador_skyline_uno = 0, // indica las coordenadas del skyline uno leidas
			contador_skyline_dos = 0, // indica las coordenadas del skyline dos leidas
			contador_skyline_mezclado = 0; // indica las coordenadas almacenadas en la mezcla de skylines 
		
		do {			
			// comprueba si el skyline uno esta antes que skyline dos
			if (skyline_uno[contador_skyline_uno][0] < skyline_dos[contador_skyline_dos][0]) 
			{
				// maxima altura entre skyline uno y la ultima altura recogida de skyline dos
				int max_altura = Math.max(skyline_uno[contador_skyline_uno][1], altura_anterior_dos);
				
				// si la maxima altura difiere de la ultima altura de la mezcla entonces almacena nuevo punto de skyline
				if (max_altura != altura_anterior_aux) 
				{
					// guarda una nueva coordenada de skyline
					skyline_mezclado[contador_skyline_mezclado][0] = skyline_uno[contador_skyline_uno][0];
					skyline_mezclado[contador_skyline_mezclado++][1] = max_altura;
					// almacena la altura de actual skyline para futuras comprobaciones
					altura_anterior_aux = max_altura;
				}
				// almacena la altura de actual skyline uno para futuras comprobaciones
				altura_anterior_uno = skyline_uno[contador_skyline_uno++][1];
			}
			// comprueba si el skyline dos esta antes que skyline uno
			else if (skyline_uno[contador_skyline_uno][0] > skyline_dos[contador_skyline_dos][0]) 
			{
				// maxima altura entre skyline dos y la ultima altura recogida de skyline uno
				int max_altura = Math.max(skyline_dos[contador_skyline_dos][1], altura_anterior_uno);
				
				// si la maxima altura difiere de la ultima altura de la mezcla entonces almacena nuevo punto de skyline
				if (max_altura != altura_anterior_aux) 
				{
					// guarda una nueva coordenada de skyline
					skyline_mezclado[contador_skyline_mezclado][0] = skyline_dos[contador_skyline_dos][0];
					skyline_mezclado[contador_skyline_mezclado++][1] = max_altura;
					// almacena la altura de actual skyline para futuras comprobaciones
					altura_anterior_aux = max_altura;
				}
				// almacena la altura de actual skyline dos para futuras comprobaciones
				altura_anterior_dos = skyline_dos[contador_skyline_dos++][1];
				
			} 
			// los dos skyline tienen una misma coordenada almacenada
			else {
				// si la altura skyline uno es mayor a: skyline dos y al skyline mezclado
				if 	( 
						( skyline_uno[contador_skyline_uno][1] > skyline_dos[contador_skyline_dos][1] ) &&
				    		( skyline_uno[contador_skyline_uno][1] != altura_anterior_aux )
					) 
				{
					// guarda una nueva coordenada de skyline
					skyline_mezclado[contador_skyline_mezclado][0] = skyline_uno[contador_skyline_uno][0];
					skyline_mezclado[contador_skyline_mezclado++][1] = skyline_uno[contador_skyline_uno][1];
					// almacena la altura de actual skyline para futuras comprobaciones
					altura_anterior_aux = skyline_uno[contador_skyline_uno][1];
				} 
				// si la altura skyline dos es mayor a skyline uno y al skyline del mezclado
				if ( 
							( skyline_dos[contador_skyline_dos][1] >= skyline_uno[contador_skyline_uno][1] ) &&
								( skyline_dos[contador_skyline_dos][1] != altura_anterior_aux )
						)
				{
					// guarda una nueva coordenada de skyline
					skyline_mezclado[contador_skyline_mezclado][0] = skyline_dos[contador_skyline_dos][0];
					skyline_mezclado[contador_skyline_mezclado++][1] = skyline_dos[contador_skyline_dos][1];
					// almacena la altura de actual skyline para futuras comprobaciones
					altura_anterior_aux = skyline_dos[contador_skyline_dos][1];
				}
				
				// almacena la altura de actual skyline dos para futuras comprobaciones
				altura_anterior_uno = skyline_uno[contador_skyline_uno++][1];
				// almacena la altura de actual skyline dos para futuras comprobaciones
				altura_anterior_dos = skyline_dos[contador_skyline_dos++][1];
			}
			
		} while ( skyline_uno.length > contador_skyline_uno && skyline_dos.length > contador_skyline_dos );
		
		// chequea las coordenadas que queden del skyline uno
		while ( skyline_uno.length > contador_skyline_uno ) 
		{
			// si la maxima altura difiere de la ultima altura de la mezcla entonces almacena nuevo punto de skyline
			if (skyline_uno[contador_skyline_uno][1] != altura_anterior_aux) 
			{
				// guarda una nueva coordenada de skyline
				skyline_mezclado[contador_skyline_mezclado][0] = skyline_uno[contador_skyline_uno][0];
				skyline_mezclado[contador_skyline_mezclado++][1] = skyline_uno[contador_skyline_uno][1];
				// almacena la altura de actual skyline para futuras comprobaciones
				altura_anterior_aux = skyline_uno[contador_skyline_uno][1];
			}
			// avance a la siguiente coordenada
			contador_skyline_uno++;
		}
		
		// chequea las coordenadas que queden del skyline dos
		while ( skyline_dos.length > contador_skyline_dos ) 
		{
			// si la maxima altura difiere de la ultima altura de la mezcla entonces almacena nuevo punto de skyline
			if (skyline_dos[contador_skyline_dos][1] != altura_anterior_aux) 
			{
				// guarda una nueva coordenada de skyline
				skyline_mezclado[contador_skyline_mezclado][0] = skyline_dos[contador_skyline_dos][0];
				skyline_mezclado[contador_skyline_mezclado++][1] = skyline_dos[contador_skyline_dos][1];
				// almacena la altura de actual skyline para futuras comprobaciones
				altura_anterior_aux = skyline_dos[contador_skyline_dos][1];
			}
			// avance a la siguiente coordenada
			contador_skyline_dos++;
		}
		
		// devuelve posiciones del skyline utilizadas
		return Arrays.copyOf(skyline_mezclado, contador_skyline_mezclado);
	}

}
